package com.hou.service;

import com.hou.dao.OrderDao;
import com.hou.dao.StockDao;
import com.hou.dao.UserDao;
import com.hou.pojo.Order;
import com.hou.pojo.Stock;
import com.hou.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author shkstart
 * @create 2021-09-06-21:10
 */
@Service
@Transactional
public class OrderServiceImpl implements OrderService{

    @Autowired
    private StockDao stockDao;

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    @Qualifier("stringRedisTemplate")
    private StringRedisTemplate redis;

    @Override
    // 秒杀操作
    public int kill(Integer id) {
        // 校验库存
        Stock stock = CheckStock(id);
        // 扣除库存
        ReduceStock(stock);
        // 创建订单
        int OrderId = CreateOrder(stock);
        // 返回id
        return OrderId;

    }

    // 获取商品信息
    @Override
    public Stock getInformationById(Integer id) {
        Stock stock = stockDao.checkStock(id);
        return stock;
    }

    // 获取md5
    @Override
    public String getMd5(Integer userId, Integer stockId) {
        // 验证用户合理性
        User user = userDao.findById(userId);
        if (user == null) {
            throw new RuntimeException("用户信息不存在");
        }

        // 检验商品合法型
        Stock stock = stockDao.checkStock(stockId);
        if (stock == null) {
            throw new RuntimeException("商品信息不存在");
        }

        //生成hashkey
        String hashKey = "KEY_"+userId+"_"+stockId;

        //生成md5
        String key = DigestUtils.md5DigestAsHex((userId+stockId+"!Q*JS#").getBytes());
        redis.opsForValue().set(hashKey,key,60, TimeUnit.SECONDS);

        return key;

    }

    // md5秒杀
    @Override
    public int kill(Integer userId, Integer stockId, String md5) {

        //验证签名
        String hashKey = "KEY_"+userId+"_"+stockId;

        // 对比不成功
        String s = redis.opsForValue().get(hashKey);
        if (s == null){
            throw new RuntimeException("没有携带验证签名");
        }
        if (!redis.opsForValue().get(hashKey).equals(md5)) {
            throw new RuntimeException("请求不合法！");
        }

        // 校验库存
        Stock stock = CheckStock(userId);
        // 扣除库存
        ReduceStock(stock);
        // 创建订单
        int OrderId = CreateOrder(stock);
        // 返回id
        return OrderId;
    }

    // 校验库存
    public Stock CheckStock(int id) {
        Stock stock = stockDao.checkStock(id);

        if(stock.getSale().equals(stock.getCount())){
            throw new RuntimeException("库存不足！！！");
        } else {
            return stock;
        }
    }

    // 扣除库存
    public void ReduceStock(Stock stock) {
        int updateRows = stockDao.updateSale(stock);
        if (updateRows == 0){
            throw new RuntimeException("抢购失败，请重试");
        }
    }

    // 创建订单
    public int CreateOrder(Stock stock){
        Order order = new Order();
        order.setName(stock.getName());
        order.setSid(stock.getId());
        order.setCreateDate(new Date());
        orderDao.createOrder(order);
        return order.getId();
    }


}
